import { Component, OnInit, OnChanges, AfterViewChecked, ViewChild, TemplateRef, OnDestroy } from '@angular/core'
import { STColumn } from '@delon/abc'
import * as dayjs from 'dayjs'
import { NzMessageService } from 'ng-zorro-antd'
import { Router, ActivatedRoute } from '@angular/router'
import { ISearchSchema, ISearchOption } from '@shared/interfaces/search'
import { ESearchType } from '@shared/enums'
import { I18NService } from '@core'
import { DashboardService } from '../dashboard.abstract.service'
import { ListBaseClass } from '@shared/classes/ListBaseClass'
import {
  Task,
  ITaskQueryParams,
  ETaskCategory,
  ETaskTypeMap,
  ETaskStatusMap,
  ETaskPostRiskOperation,
} from '@shared/interfaces/task'
import { DataService } from '@shared/services/data.service'
import { PublicService } from '@shared/services/public.service'
import { SettingsService } from '@delon/theme'

const firstDayOfMonth = dayjs()
  .startOf('month')
  .format('YYYY-MM-DDTHH:mm:ssZ')
const tomorrow = dayjs()
  .startOf('day')
  .add(1, 'day')
  .format('YYYY-MM-DDTHH:mm:ssZ')

@Component({
  selector: 'app-dashboard-todo',
  templateUrl: './tasks.component.html',
  styleUrls: ['../../../shared/styles/table.less'],
})
export class DashboardTasksComponent extends ListBaseClass<Task, ITaskQueryParams> implements OnInit, OnDestroy {
  @ViewChild('tplAcquirer') tplAcquirer: TemplateRef<void>
  @ViewChild('tplGroup') tplGroup: TemplateRef<void>
  @ViewChild('tplMerchant') tplMerchant: TemplateRef<void>
  @ViewChild('tplStore') tplStore: TemplateRef<void>

  /** 任务类型 */
  type: ETaskCategory
  params: ITaskQueryParams
  searchSchema: ISearchSchema[] = []
  data: Task[] = []
  typeOptions: ISearchOption[] = []
  statusOptions: ISearchOption[] = []
  ETaskPostRiskOperation = ETaskPostRiskOperation
  columns: STColumn[] = []

  constructor(
    public msg: NzMessageService,
    public i18n: I18NService,
    public router: Router,
    public route: ActivatedRoute,
    public publicService: PublicService,
    public settings: SettingsService,
    private dashboardService: DashboardService,
    private dataService: DataService,
  ) {
    super(msg, i18n, route, router, settings)
  }

  ngOnInit() {
    this.genTaskTypeOptions()
    this.genTaskStatusOptions()
    this.route.params.subscribe(params => {
      const { type } = params
      if (!this.type || type !== this.type) {
        this.type = type
        this.reload()
      }
    })
  }

  ngOnDestroy() {
    this.dataService.resetTask()
  }

  reload(): void {
    this.resetSelectAAMS()
    this.initParams()
    this.initSearchSchema()
    this.queryTableDataWithParams()
    this.initColumns()
    this.initialAAMSFilter()
  }

  initParams(): void {
    this.params = {
      updatedAtFrom: firstDayOfMonth,
      updatedAtTo: tomorrow,
      submittedAtFrom: firstDayOfMonth,
      submittedAtTo: tomorrow,
      size: this.defaultSize,
      page: this.defaultPi,
    }
  }

  resetSelectAAMS(): void {
    this.selectedAcquirer = null
    this.selectedGroup = null
    this.selectedMerchant = null
    this.selectedStore = null
  }

  initialAAMSFilter(): void {
    this.initAcquirer()
    this.initAgent()
    this.initMerchant()
    this.initStore()
  }

  queryTableDataWithParams(): void {
    this.loading = true
    this.dashboardService
      .getList(this.params, this.type)
      .subscribe(this.renderList.bind(this), this.getListError.bind(this))
  }

  viewDetail(data) {
    this.dataService.setTask(data)
    const { jobID, insCode } = data
    if (this.taskOperation(data.operation)) {
      return this.router.navigate([`../${jobID}/postRisk`], {
        relativeTo: this.route,
      })
    }
    this.router.navigate([`../${jobID}`], {
      relativeTo: this.route,
    })
  }

  judgeStatus(currentStep: number): string {
    if (currentStep === 1) {
      return this.publicService.trans(ETaskStatusMap.approved)
    }
    if (currentStep === 2) {
      return this.publicService.trans(ETaskStatusMap.rejected)
    }
    return this.publicService.trans(ETaskStatusMap.auditing)
  }

  initColumns(): void {
    this.columns = [
      {
        title: '任务编号',
        i18n: this.trans('TASK.AUDIT.JOBID'),
        index: 'jobID',
        type: 'link',
        click: this.viewDetail.bind(this),
        className: 'text-center',
        fixed: 'left',
        width: 150,
      },
      {
        title: '创建时间',
        i18n: this.trans('GENERAL.INFO.CREATED_AT'),
        type: 'date',
        index: 'createTime',
        width: 250,
      },
      {
        title: '任务类别',
        i18n: this.trans('TASK.AUDIT.AUDITTYPE'),
        index: 'auditType',
        className: 'text-center',
        render: 'auditType',
        width: 200,
      },
      {
        title: '经办用户',
        i18n: this.trans('TASK.AUDIT.CREATOR'),
        index: 'creator',
        className: 'text-center',
        width: 150,
      },
      {
        title: '更新时间',
        i18n: this.trans('GENERAL.INFO.UPDATED_AT'),
        type: 'date',
        index: 'updateTime',
        width: 200,
      },
      {
        title: '任务状态',
        i18n: this.trans('TASK.AUDIT.STATUS'),
        index: 'status',
        className: 'text-center',
        render: 'status',
        width: 100,
      },
    ]
  }

  private initSearchSchema(): void {
    this.searchSchema = [
      {
        label: '创建时间',
        labelI18n: 'GENERAL.INFO.CREATED_AT',
        /** As all the dateRange require 2 key(start, end) post to backend, so we make it flexible to change the key name */
        index: ['submittedAtFrom', 'submittedAtTo'],
        type: ESearchType.dateRange,
        value: [firstDayOfMonth, tomorrow],
      },
      {
        label: '更新时间',
        labelI18n: 'GENERAL.INFO.UPDATED_AT',
        /** As all the dateRange require 2 key(start, end) post to backend, so we make it flexible to change the key name */
        index: ['updatedAtFrom', 'updatedAtTo'],
        type: ESearchType.dateRange,
        value: [firstDayOfMonth, tomorrow],
      },
      {
        label: '任务编号',
        labelI18n: 'TASK.AUDIT.JOBID',
        index: 'jobID',
        type: ESearchType.input,
      },
      {
        label: '任务类别',
        labelI18n: 'TASK.AUDIT.AUDITTYPE',
        index: 'type',
        type: ESearchType.selection,
        options: this.typeOptions,
      },
      {
        label: '任务状态',
        labelI18n: 'TASK.AUDIT.STATUS',
        index: 'status',
        type: ESearchType.selection,
        options: this.statusOptions,
      },
      {
        label: '机构',
        labelI18n: 'GENERAL.BIZ_LEVEL.INSTITUTION',
        index: 'insCode',
        component: this.tplAcquirer,
        customFunc: () => this.selectedAcquirer && this.selectedAcquirer.code,
      },
      /** 需求确定先隐藏 */
      // {
      //   label: '集团',
      //   labelI18n: 'GENERAL.BIZ_LEVEL.AGENT',
      //   index: 'agentCode',
      //   component: this.tplGroup,
      //   customFunc: () => this.selectedGroup && this.selectedGroup.code,
      // },
      // {
      //   label: '商户',
      //   labelI18n: 'GENERAL.BIZ_LEVEL.MERCHANT',
      //   index: 'intMerCode',
      //   component: this.tplMerchant,
      //   customFunc: () => this.selectedMerchant && this.selectedMerchant.code,
      // },
      // {
      //   label: '门店',
      //   labelI18n: 'GENERAL.BIZ_LEVEL.STORE',
      //   index: 'intStoreCode',
      //   component: this.tplStore,
      //   customFunc: () => this.selectedStore && this.selectedStore.code,
      // },
    ]
  }

  taskOperation(type: string): Boolean {
    for (const key in this.ETaskPostRiskOperation) {
      if (type === this.ETaskPostRiskOperation[key]) {
        return true
      }
    }
    return false
  }

  getAuditTypeValue(auditType: string): string {
    try {
      return this.publicService.trans(ETaskTypeMap[auditType])
    } catch (e) {
      return this.publicService.trans('GENERAL.INFO.NONE')
    }
  }

  getAuditStatus(task: Task): string {
    try {
      return task.status ? this.publicService.trans(ETaskStatusMap[task.status]) : this.judgeStatus(task.currentStep)
    } catch (e) {
      return this.publicService.trans('GENERAL.INFO.NONE')
    }
  }

  private genTaskTypeOptions(): void {
    this.typeOptions = this.publicService.genOptions(ETaskTypeMap)
  }

  private genTaskStatusOptions(): void {
    this.statusOptions = this.publicService.genOptions(ETaskStatusMap)
  }

}
